package top.broncho.mvvm.di

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import dagger.Binds
import dagger.Module
import dagger.multibindings.IntoMap
import top.broncho.gank.ui.activity.*
import top.broncho.gank.ui.fragment.*
import top.broncho.mvvm.di.annotation.ViewModelKey

@Module
abstract class ViewModelModule {

    // @Binds 类似于 @Provides，在使用接口声明时使用，区别是 @Binds 用于修饰抽象类中的抽象方法的
    // 这个方法必须返回接口或抽象类，比如 ViewModel，不能直接返回 MainViewModule
    // 方法的参数就是这个方法返回的是注入的对象，类似@Provides修饰的方法返回的对象
    // 这里的 MainViewModule 会通过上述声明的构造器注入自动构建
    @Binds
    @IntoMap
    //@MapKey的封装注解
    @ViewModelKey(MainViewModel::class)
    abstract fun bindMainViewModel(viewModule: MainViewModel): ViewModel

    @Binds
    @IntoMap
    @ViewModelKey(HomeViewModel::class)
    abstract fun bindHomeViewModel(viewModule: HomeViewModel): ViewModel

    @Binds
    @IntoMap
    @ViewModelKey(SquareViewModel::class)
    abstract fun bindSquareViewModel(viewModule: SquareViewModel): ViewModel

    @Binds
    @IntoMap
    @ViewModelKey(WeChatViewModel::class)
    abstract fun bindWeChatViewModel(viewModule: WeChatViewModel): ViewModel

    @Binds
    @IntoMap
    @ViewModelKey(KnowledgeViewModel::class)
    abstract fun bindKnowledgeViewModel(viewModule: KnowledgeViewModel): ViewModel

    @Binds
    @IntoMap
    @ViewModelKey(KnowledgeTreeViewModel::class)
    abstract fun bindKnowledgeTreeViewModel(viewModule: KnowledgeTreeViewModel): ViewModel

    @Binds
    @IntoMap
    @ViewModelKey(NavigationViewModel::class)
    abstract fun bindNavigationViewModel(viewModule: NavigationViewModel): ViewModel

    @Binds
    @IntoMap
    @ViewModelKey(ProjectViewModel::class)
    abstract fun bindProjectViewModel(viewModule: ProjectViewModel): ViewModel

    @Binds
    @IntoMap
    @ViewModelKey(ProjectListViewModel::class)
    abstract fun bindProjectListViewModel(viewModule: ProjectListViewModel): ViewModel

    @Binds
    @IntoMap
    @ViewModelKey(LoginViewModel::class)
    abstract fun bindLoginViewModel(viewModule: LoginViewModel): ViewModel

    @Binds
    @IntoMap
    @ViewModelKey(RegisterViewModel::class)
    abstract fun bindRegisterViewModel(viewModule: RegisterViewModel): ViewModel

    @Binds
    @IntoMap
    @ViewModelKey(SearchViewModel::class)
    abstract fun bindSearchViewModel(viewModule: SearchViewModel): ViewModel

    @Binds
    @IntoMap
    @ViewModelKey(SearchListViewModel::class)
    abstract fun bindSearchListViewModel(viewModule: SearchListViewModel): ViewModel

    @Binds
    @IntoMap
    @ViewModelKey(RankViewModel::class)
    abstract fun bindRankViewModel(viewModule: RankViewModel): ViewModel

    @Binds
    @IntoMap
    @ViewModelKey(CollectViewModel::class)
    abstract fun bindCollectViewModel(viewModule: CollectViewModel): ViewModel

    @Binds
    @IntoMap
    @ViewModelKey(top.broncho.gank.ui.main.score.ScoreViewModel::class)
    abstract fun bindScoreViewModel(viewModule: top.broncho.gank.ui.main.score.ScoreViewModel): ViewModel

    @Binds
    @IntoMap
    @ViewModelKey(AddTodoViewModel::class)
    abstract fun bindAddTodoViewModel(viewModule: AddTodoViewModel): ViewModel

    @Binds
    @IntoMap
    @ViewModelKey(ShareArticleViewModel::class)
    abstract fun bindShareArticleViewModel(viewModule: ShareArticleViewModel): ViewModel

    @Binds
    @IntoMap
    @ViewModelKey(ShareViewModel::class)
    abstract fun bindShareViewModel(viewModule: ShareViewModel): ViewModel

    @Binds
    @IntoMap
    @ViewModelKey(TodoViewModel::class)
    abstract fun bindTodoViewModel(viewModule: TodoViewModel): ViewModel

    @Binds
    @IntoMap
    @ViewModelKey(ContentViewModel::class)
    abstract fun bindContentViewModel(viewModule: ContentViewModel): ViewModel

    @Binds
    abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
}